﻿@using Gurux.DLMS.AMI.Shared.DTOs;
@using Gurux.DLMS.AMI.Shared.Enums;
@using Gurux.DLMS.AMI.Shared.Rest;
@using Gurux.DLMS.Enums;

@inject HttpClient Http
@inject IGXNotifier Notifier
<DropdownSearch Disabled="@Disabled"
                Context="item"
                ItemsProvider="GetObjects"
@bind-Value="Value">
    <ItemContent>
        @if (item?.Template != null)
        {
            if (item.Template.Name == null)
            {
                @(item.Template.LogicalName + " " + ((ObjectType)item.Template.ObjectType))
            }
            else
            {
                @(item.Template.LogicalName + " " + item.Template.Name)
            }
        }
    </ItemContent>
</DropdownSearch>

@code {

    /// <summary>
    /// Target object.
    /// </summary>
    [Parameter]
    public GXObject? Value { get; set; }

    /// <summary>
    /// Notified when value is updated.
    /// </summary>
    [Parameter]
    public EventCallback<GXObject?> ValueChanged { get; set; }

    /// <summary>
    /// Target object filter.
    /// </summary>
    [Parameter]
    public GXObject? Filter { get; set; }

    /// <summary>
    /// Notified when object filter is updated.
    /// </summary>
    [Parameter]
    public EventCallback<GXObject?> FilterChanged { get; set; }


    /// <summary>
    /// Is the object selector read-only.
    /// </summary>
    [Parameter]
    public bool Disabled
    {
        get;
        set;
    }

    private async ValueTask<ItemsProviderResult<GXObject?>> GetObjects(GXItemsProviderRequest request)
    {
        //Don't clear status or error is lost.
        Notifier?.ProgressStart();
        try
        {
            Filter.Template.LogicalName = null;
            if (!string.IsNullOrEmpty(request.Filter))
            {
                try
                {
                    var ln = GXDLMSConverter.LogicalNameToBytes(request.Filter);
                    if (ln != null && ln.Length == 6)
                    {
                        Filter.Template.LogicalName = request.Filter.Trim();
                    }
                }
                catch (Exception)
                {
                    //It's OK if this fails.
                }
                if (Filter.Template.LogicalName == null)
                {
                    Filter.Template.Name = request.Filter.Trim();
                }
            }
            else
            {
                //Reset filter.
                Filter.Template.LogicalName = null;
                Filter.Template.Name = null;
            }
            ListObjects req = new ListObjects()
                {
                    Index = (UInt64)request.StartIndex,
                    Count = (UInt64)request.Count,
                    Filter = Filter,
                    OrderBy = request.OrderBy,
                    Descending = request.Descending,
                    AllUsers = request.ShowAllUserData,
                };
            var ret = await Http.PostAsJson<ListObjectsResponse>("api/Object/List", req, request.CancellationToken);
            //Update device for late binding.
            if (ret != null)
            {
                foreach (var it in ret.Objects)
                {
                    it.Device = Filter.Device;
                }
                return new ItemsProviderResult<GXObject?>(ret.Objects, ret.Count);
            }
        }
        catch (TaskCanceledException)
        {
            //Let the table component handle this.
            throw;
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
        return default;
    }

    protected override void OnInitialized()
    {
        if (Filter == null)
        {
            Filter = new GXObject()
                {
                    Device = Value?.Device,
                };
        }
        if (Filter?.Device == null)
        {
            throw new ArgumentNullException(nameof(Filter), "The device has not been set for the filter.");
        }
        if (Filter.Template == null)
        {
            Filter.Template = new GXObjectTemplate();
        }
    }
}
